/* 
 * Author: apleilx
 *
 * Created on 2015年10月9日, 上午10:07
 */

#ifndef _SIMP_FAT_M_H
#define	_SIMP_FAT_M_H

#include "stdint.h"
#include "rtctime.h"

#ifdef	__cplusplus
extern "C" {
#endif	

	#define SIMP_FAT_NAME_LEN    24

    /*-------------------------------------------------------------------------------------------------------*
    * 用于管理一次性文件存储
    * 仅支持文件处理，不包含文件夹管理
    * 存储以page为基本单位
    *-------------------------------------------------------------------------------------------------------*/

    typedef enum
    {
        SIMP_FAT_OK = 0,
        SIMP_FAT_FLASH_INFO,
        SIMP_FAT_HAL_API,
    } simp_fat_err;

    typedef enum
    {
        SIMP_FLASH_RW_RAND = 0,
        SIMP_FLASH_RW_PAGE = 1,
    } simp_fat_flash_type;

    typedef enum
    {
        SIMP_FAT_OPT_IDLE = 0,
        SIMP_FAT_OPT_OPEN,
        SIMP_FAT_OPT_READ,
        SIMP_FAT_OPT_WRITE,
    } simp_fat_opt_st;

    #define SIMP_FAT_MODE_RD  1   //只读
    #define SIMP_FAT_MODE_WR  2   //读写

    struct simp_fat_info
    {
        uint32_t start_page;	//起始页
        uint32_t size;      	//文件尺寸-字节数
        uint8_t name[SIMP_FAT_NAME_LEN];   //文件名
    };

    struct simp_fat_str
    {
        struct 
        {
            uint32_t page_per_block;
            uint32_t page_size;      //扇区尺寸
            uint32_t block_amount;   //扇区数量
        } flash;

        struct
        {
            simp_fat_err(*read)(void *buff, uint32_t sector_start, uint32_t sector_len);   //读取扇区
            simp_fat_err(*write)(void *buff, uint32_t sector_start, uint32_t sector_len);  //写入扇区
        } hal;

        void *buff;                //应大于或等于sector_size尺寸
        uint32_t buff_size;
        uint8_t flash_st;           //存储器状态
        simp_fat_flash_type flash_type;         //0-支持随机地址读写，1-仅页读页写
    };
    
    typedef struct simp_fat_str simp_fat_type;

    struct simp_fat_file_str
    {
        simp_fat_type * fat; 		//文件分配表
        uint8_t file_mode;
        uint32_t fat_site;  		//文件信息在分配表中的位置
        uint32_t file_size; 		//文件尺寸
        uint32_t file_site; 		//文件位置
        uint32_t dat_site;  		//当前数据指针位置
        simp_fat_opt_st opt_st; 	//操作状态
        void *buff;                //应大于或等于sector_size尺寸
    };

    typedef struct simp_fat_file_str simp_fat_file_type;

    /*****************************************************************************
    * @brief  初始化分配表.
    * \param[in] fat     文件表
    * \param[in] sector_size    扇区尺寸
    * \param[in] sector_len     扇区个数
    * \param[in] read      读函数
    * \param[in] write     写函数
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_mount(simp_fat_type *fat, uint32_t sector_size, uint32_t sector_len, void *read, void *write);

    /*****************************************************************************
    * @brief  flash状态更新.
    * \param[in] fat    文件表
    * \param[in] st     状态
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_flash_st_update(simp_fat_type *fat, uint8_t st);

    /*****************************************************************************
    * @brief  格式化分配表.
    * \param[in] fat     文件表
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_format(simp_fat_type *fat);

    /*****************************************************************************
    * @brief  打开文件.
    * \param[in] fil      文件
    * \param[in] name     文件名
    * \param[in] mode     打开方式 w:可写，r可读，+可创建，a+强制创建
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_open(simp_fat_type *fat, simp_fat_file_type *fil, char *name, char *mode);

    /*****************************************************************************
    * @brief  写入文件.
    * \param[in] fil      文件
    * \param[in] buff     数据缓冲区
    * \param[in] len      写入长度
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_write(simp_fat_file_type *fil, void *buff, uint32_t len);

    /*****************************************************************************
    * @brief  读取文件.
    * \param[in] fil      文件
    * \param[in] buff     数据缓冲区
    * \param[in] len      读取长度
    * \param[in] read_len_back      实际读取的长度
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_read(simp_fat_file_type *fil, void *buff, uint32_t len, uint32_t *read_len_back);

    /*****************************************************************************
    * @brief  关闭文件.
    * \param[in] fil      文件
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_close(simp_fat_file_type *fil);

    /*****************************************************************************
    * @brief  文件当前相间指针设置.
    * \param[in] fil      文件
    * \param[in] site     目标位置
    * \retval: 执行结果
    *****************************************************************************/
    simp_fat_err simp_fat_seek(simp_fat_file_type *fil, uint32_t site);


#ifdef	__cplusplus
}
#endif

#endif	/* _SIMP_FAT_M_H */
